#include <kos.h>
#include "menu.h"
#include "font.h"
#include "utils.h"
#include "main.h"

int sound_qualities[] = {0,1,-1}; //4800,9600,14400,19200,-1};
int cpu_68k_options[] = {0,1,-1};
int render_options[] = {0,1,-1};
int mode_options[] = {0x00, 0x01, 0x81, 0xC1, -1};
char *mode_name[] = {"Auto", "Jap", "USA", "Eur"};

extern int force_mode;

static int oldbutt = -1;
static char* file_selection = 0;

typedef struct rom_info
{
  char *name;
  char *filename;
}
rom_info_t;

static rom_info_t *roms = 0;
static int total_roms = 0; 
static int rom_scroll = 0;
static int rom_sel    = 0;
static int sq_sel     = 1;
static int cpu_sel    = 0;
static int render_sel = 1;
static int mode_sel   = 0;

#define ROM_MAX 22

char *files_browser();

/* Configurable options */
options_t dc_options =
{
	0,						  /* Frameskip */
	487,	          /* M68k clock speed */
	228,     			  /* Z80 clock speed */
  SE_DEFAULT,     /* sound enabled */
  FPS_DEFAULT,    /* fps display */
  CPU68K_DEFAULT, /* Type of M68K CPU to use 0 = C68K, 1 = FAME */
  RENDER_DEFAULT
};

#if defined(USE_ROMDISK)
extern uint8 romdisk[];
KOS_INIT_ROMDISK(romdisk);
#endif

extern void dc_init();
extern void test_exec(char *filename);

extern fnt_info_t font;

void read_roms(void)
{
  FILE *fp = 0;

  char name[256];

  sprintf(name,"%s/roms.txt",data_dir);

  if ((fp = fopen(name,"rb")))
  {
    char *t;
    char line[1024];

    while (fgets(line,sizeof(line),fp))
    {
      roms = (rom_info_t *)realloc(roms,(total_roms+1)*sizeof(rom_info_t));

      if ((t=strtok(line,UTL_WHITESPACE)))
      {
        roms[total_roms].filename = strdup(t);
        roms[total_roms].name = strdup(t+(strlen(t)+1));
        total_roms++;
      }
    }

    fclose(fp);
  }

}

char *rom_human_name = NULL;

char *files_browser() 
{
	maple_device_t	*dev;
	cont_state_t	  *state;
	int		           i;
						
  char browse_txt[80] = "";
  int repeat  = 0;

	pvr_set_bg_color(0, 0, 0);

	while(1)
	{
		pvr_wait_ready();
		pvr_scene_begin();

		pvr_list_begin(PVR_LIST_TR_POLY);

    sprintf(browse_txt, "[Buttons (X): %s] [Sound (Y): %s] [CPU (B): %s] [Video (A): %s] [Mode (L): %s]",
              (dc_options.fps_display?"6":"3"),
              (dc_options.sound_enabled ? "On" : "Off"),
              (dc_options.cpu68k_type == 0 ? "C68K" : "FAME"),
              (dc_options.render_type ? "HW" : "SW"),
              mode_name[mode_sel]);

    fnt_write_simple(&font,
                     browse_txt,
                     24, 24,
                     14,
                     0.48,
                     1,
                     0xFFFF00);

    for(i=0; i+rom_scroll < total_roms && i < ROM_MAX; i++)
    {
      fnt_write_simple(&font,
                       roms[i+rom_scroll].name,
                       40, 48+i*18,
                       14,
                       0.5,
                       ((i+rom_scroll)==rom_sel)?1:0.5,
                       0xFFFFFF);    
    }

		pvr_list_finish();

		pvr_scene_finish();

		/* Find a controller */
		dev = maple_enum_type(0, MAPLE_FUNC_CONTROLLER);

		/* Get controller state */
		state = (cont_state_t *)maple_dev_status(dev);
		if(!state)
			continue;

    if (state->ltrig > 128)
      state->buttons |= CONT_C;

    if (state->rtrig > 128)
      state->buttons |= CONT_Z;

    if (oldbutt && state->buttons == oldbutt)
      repeat++;
    else
      repeat=0;

    if (repeat>20 || state->buttons != oldbutt)
    {
      if ((state->buttons & CONT_A) &&
          (state->buttons & CONT_B) &&
          (state->buttons & CONT_X))
        break;

      if(state->buttons & CONT_DPAD_UP)
        rom_sel--;
      else if(state->buttons & CONT_DPAD_DOWN)
        rom_sel++;
      else if (state->buttons & CONT_DPAD_RIGHT)
      {
        rom_scroll += ROM_MAX/2;

        if (rom_scroll > total_roms - ROM_MAX)
          rom_scroll = total_roms-ROM_MAX;

        rom_sel = rom_scroll + ROM_MAX/2;
      }
      else if (state->buttons & CONT_DPAD_LEFT)
      {
        rom_scroll -= ROM_MAX/2;

        if (rom_scroll < 0)
          rom_scroll = 0;

        rom_sel = rom_scroll + ROM_MAX/2;
      }

      if(rom_sel<0)
        rom_sel=0;
      else if (rom_sel>=total_roms)
        rom_sel=total_roms-1;

      if (rom_sel> (rom_scroll+ROM_MAX-1))
        rom_scroll++;
      if (rom_sel<rom_scroll)
        rom_scroll--;

      if ((state->buttons & CONT_X) && !(oldbutt & CONT_X))
        dc_options.fps_display = !dc_options.fps_display;

      if ((state->buttons & CONT_Y) && !(oldbutt & CONT_Y))
      {
        sq_sel++;

        REDO_SQ_SEL:

        dc_options.sound_enabled = sound_qualities[sq_sel];

        if (dc_options.sound_enabled == -1)
        {
          sq_sel = 0;
          goto REDO_SQ_SEL;
        }

        if (dc_options.sound_enabled)
          dc_options.z80_clock = 228;
        else
          dc_options.z80_clock = 25;
      }

      if ((state->buttons & CONT_B) && !(oldbutt & CONT_B))
      {
        cpu_sel++;

        REDO_CPU_SEL:

        dc_options.cpu68k_type = cpu_68k_options[cpu_sel];

        if (dc_options.cpu68k_type == -1)
        {
          cpu_sel = 0;
          goto REDO_CPU_SEL;
        }
      }

      if ((state->buttons & CONT_A) && !(oldbutt & CONT_A))
      {
        render_sel++;

        REDO_RENDER_SEL:

        dc_options.render_type = render_options[render_sel];

        if (dc_options.render_type == -1)
        {
          render_sel = 0;
          goto REDO_RENDER_SEL;
        }
      }

      if ((state->buttons & CONT_C) && !(oldbutt & CONT_C))
      {
        mode_sel++;

        REDO_MODE_SEL:

        force_mode = mode_options[mode_sel];

        if (force_mode == -1)
        {
          mode_sel = 0;
          goto REDO_MODE_SEL;
        }
      }


      if ((state->buttons & CONT_START) && !(oldbutt & CONT_START))
      {
        char game_path[256];

	sprintf(game_path, "%s/roms/%s", data_dir, roms[rom_sel].filename);
	rom_human_name = roms[rom_sel].name;

        /* -------------------------------------------------- */
        /* So, when we come back, we think we're in repeat!!! */
        /* -------------------------------------------------- */
        oldbutt = CONT_C | CONT_Z | CONT_START;

        return(strdup(game_path));
      }

      oldbutt = state->buttons;
    }
	}

  return 0;
}

int main(int argc, char *argv[])
{
	dc_init();

  read_roms();

  while((file_selection = files_browser()) != 0)
  {
  test_exec(file_selection);

    free(file_selection);
    file_selection = 0;
  }

	dc_shutdown();

	return 0;
}

